//
//  HYQWebView.m
//  HYQWebkit_Example
//
//  Created by zhuxingjian on 2018/8/20.
//  Copyright © 2018年 zxj1989. All rights reserved.
//

#import "HYQWebView.h"

#define HYQ_JS_BRIDGE_OBJ_NAME     @"bridge"

@interface HYQWebView () <UIWebViewDelegate>
{
    NSURLConnection *_urlConnection;
    NSURLRequest *_request;
    BOOL _authenticated;
}
@property (nonatomic, strong) HYQBaseBridgeManager *bridgeManager;
@property (nonatomic, strong) JSContext *context;

@end

@implementation HYQWebView

- (instancetype)initWithBridgeManager:(HYQBaseBridgeManager *)bridgeManager;
{
    if (self = [super init]) {
        _bridgeManager = bridgeManager;
        self.delegate = self;
    }
    return self;
}

- (void)loadWebViewWithURLString:(NSString *)urlString
{
    self.context = [self valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    self.context[HYQ_JS_BRIDGE_OBJ_NAME] = self.bridgeManager;
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    [self loadRequest:request];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{
    if (self.shouldStartLoadBlock) {
        return self.shouldStartLoadBlock(self,request);
    }
    if (NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_8_0 && NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_9_x_Max) {
        if (!_authenticated) {
            _authenticated =NO;
            _urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; // 网上好多教程这句写的request写的是_request
            _request = request; //网上好多教程这句代码忘记加了
            [_urlConnection start];
            return NO;
        }
    }
    return YES;
}

- (void)webViewDidStartLoad:(UIWebView *)webView;
{
    if (self.didStartLoadBlock) {
        self.didStartLoadBlock(self);
    }
}

- (void)webViewDidFinishLoad:(UIWebView *)webView;
{
    if (self.didFinishLoadBlock) {
        self.didFinishLoadBlock(self);
    }
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
{
    if (self.didFailLoadBlock) {
        self.didStartLoadBlock(self);
    }
}

-(NSInteger)checkStatusCode:(UIWebView *)webView
{
    NSCachedURLResponse *resp = [[NSURLCache sharedURLCache] cachedResponseForRequest:webView.request];
    NSInteger statusCode = 200;
    NSError *error = nil;
    if(resp == nil){
        NSHTTPURLResponse *response = nil;
        NSURLRequest *request;
        request = webView.request;
        [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    }
    else{
        statusCode=((NSHTTPURLResponse*)resp.response).statusCode;
        error=[NSError errorWithDomain:@"this is user domain" code:statusCode userInfo:@{@"NSErrorFailingURLKey":webView.request.URL.absoluteString}];
    }
    return statusCode;
}


- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge previousFailureCount] == 0)
    {
        _authenticated = YES;
        NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
    } else
    {
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    // remake a webview call now that authentication has passed ok.
    _authenticated = YES;
    [self loadRequest:_request]; //  self.webView替换成自己的webview
    // Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)
    [_urlConnection cancel];
}

// We use this method is to accept an untrusted site which unfortunately we need to do, as our PVM servers are self signed.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)callJSWithName:(NSString *)functionName param:(id)param
{
    if (!functionName) {
        return;
    }
    NSMutableString *methodName = [[NSMutableString alloc] initWithString:functionName];
    NSMutableString *paramter = [[NSMutableString alloc] initWithString:@"("];
    if(!param){
        [paramter appendString:@")"];
    }else if([param isKindOfClass:[NSString class]]) {
        [paramter appendFormat:@"'%@')",param];
    }else if([param isKindOfClass:[NSNumber class]]) {
        [paramter appendFormat:@"%@)",param];
    }else {
        NSData *data = [NSJSONSerialization dataWithJSONObject:param
                                                       options:NSJSONReadingMutableLeaves | NSJSONReadingAllowFragments
                                                         error:nil];
        if (data == nil) {
            [paramter appendFormat:@")"];
            return;
        }
        NSString *string = [[NSString alloc] initWithData:data
                                                 encoding:NSUTF8StringEncoding];
        [paramter appendFormat:@"'%@')",string];
    }
    [methodName appendString:paramter];
    if (![[NSThread currentThread] isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self stringByEvaluatingJavaScriptFromString:methodName];
        });
    }else {
        [self stringByEvaluatingJavaScriptFromString:methodName];
    }
}


@end
